﻿    var jQuery = window.jQuery,
       undefined,
      _, //temp variable of prototypes
      mqCmdId = 'mathquill-command-id',
      mqBlockId = 'mathquill-block-id',
      min = Math.min,
      max = Math.max;

    var __slice = [].slice;

    function noop() { }

    /**
     * sugar to make defining lots of commands easier.
     * TODO: rethink this.
     */
    function bind(cons /*, args... */) {
        var args = __slice.call(arguments, 1);
        return function () {
            return cons.apply(this, args);
        };
    }

    /**
     * a development-only debug method.  This definition and all
     * calls to `pray` will be stripped from the minified
     * build of mathquill.
     *
     * This function must be called by name to be removed
     * at compile time.  Do not define another function
     * with the same name, and only call this function by
     * name.
     */
    function pray(message, cond) {
        if (!cond) throw new Error('prayer failed: ' + message);
    }
    var P = (function (prototype, ownProperty, undefined) {
        // helper functions that also help minification
        function isObject(o) { return typeof o === 'object'; }
        function isFunction(f) { return typeof f === 'function'; }

        // a function that gets reused to make uninitialized objects
        function BareConstructor() { }

        function P(_superclass /* = Object */, definition) {
            // handle the case where no superclass is given
            if (definition === undefined) {
                definition = _superclass;
                _superclass = Object;
            }

            // C is the class to be returned.
            //
            // It delegates to instantiating an instance of `Bare`, so that it
            // will always return a new instance regardless of the calling
            // context.
            //
            //  TODO: the Chrome inspector shows all created objects as `C`
            //        rather than `Object`.  Setting the .name property seems to
            //        have no effect.  Is there a way to override this behavior?
            function C() {
                var self = new Bare;
                if (isFunction(self.init)) self.init.apply(self, arguments);
                return self;
            }

            // C.Bare is a class with a noop constructor.  Its prototype is the
            // same as C, so that instances of C.Bare are also instances of C.
            // New objects can be allocated without initialization by calling
            // `new MyClass.Bare`.
            function Bare() { }
            C.Bare = Bare;

            // Set up the prototype of the new class.
            var _super = BareConstructor[prototype] = _superclass[prototype];
            var proto = Bare[prototype] = C[prototype] = new BareConstructor;

            // other variables, as a minifier optimization
            var extensions;


            // set the constructor property on the prototype, for convenience
            proto.constructor = C;

            C.mixin = function (def) {
                Bare[prototype] = C[prototype] = P(C, def)[prototype];
                return C;
            }

            return (C.open = function (def) {
                extensions = {};

                if (isFunction(def)) {
                    // call the defining function with all the arguments you need
                    // extensions captures the return value.
                    extensions = def.call(C, proto, _super, C, _superclass);
                }
                else if (isObject(def)) {
                    // if you passed an object instead, we'll take it
                    extensions = def;
                }

                // ...and extend it
                if (isObject(extensions)) {
                    for (var ext in extensions) {
                        if (ownProperty.call(extensions, ext)) {
                            proto[ext] = extensions[ext];
                        }
                    }
                }

                // if there's no init, we assume we're inheriting a non-pjs class, so
                // we default to applying the superclass's constructor.
                if (!isFunction(proto.init)) {
                    proto.init = _superclass;
                }

                return C;
            })(definition);
        }

        // ship it
        return P;

        // as a minifier optimization, we've closured in a few helper functions
        // and the string 'prototype' (C[p] is much shorter than C.prototype)
    })('prototype', ({}).hasOwnProperty);